package cn.jbolt.wechat.common;


import cn.jbolt.wechat.common.miniapp.WechatMaContext;
import cn.jbolt.wechat.common.mp.WechatMpContext;

import java.util.Objects;
import java.util.function.Supplier;

/**
 * 公众平台API
 * 利用 use 方法代替拦截器设定 appid
 */
public class JBoltWechatApi {
	private static final WechatApiResult NO_ASSIGN_TYPE=new WechatApiResult("{errorCode:-1000,errmsg:\"API调用未指明正确的账号类型\"}");
	public static enum Type{
		MP,//服务号 订阅号
		APP,//小程序
		WORK,//企业微信
	}
	private Type type;
	private String appId;
	/**
	 * 核心调用创建实例对象 传入调用账号的appId
	 * @param appId
	 * @return
	 */
	public static JBoltWechatApi use(String appId) {
		Objects.requireNonNull(appId, "appId can not be null");
		return new JBoltWechatApi(appId);
	}
	/**
	 * 核心调用创建实例对象 传入调用账号的appId
	 * @param appId
	 * @return
	 */
	public static JBoltWechatApi use(String appId,Type type) {
		Objects.requireNonNull(appId, "appId can not be null");
		return new JBoltWechatApi(appId,type);
	}

	private JBoltWechatApi(String appId) {
		this(appId, Type.MP);
	}

	private JBoltWechatApi(String appId, Type type) {
		this.appId = appId;
		this.type=type;
	}
	/**
	 * 核心call
	 * @param function
	 * @return
	 */
	public <T> T call(Supplier<T> function) {
		T result=null;
		switch (type) {
		case APP:
			result= callWxApp(function);
			break;
		case MP:
			result= callWxMp(function);
			break;
		case WORK:
			result=callWork(function);
			break;
		default:
			result=(T)NO_ASSIGN_TYPE;
			break;
		}
		return result;
	}
	/**
	 * 调用微信小程序的
	 * @param function
	 * @return
	 */
	private <T> T callWxApp(Supplier<T> function) {
		try {
			WechatMaContext.switchTo(appId);
			return function.get();
		} finally {
			WechatMaContext.switchOver();

		}
	}
	/**
	 * 调用普通服务号 订阅号
	 * @param function
	 * @return
	 */
	private <T> T callWxMp(Supplier<T> function) {
		try {
			WechatMpContext.switchTo(appId);
			return function.get();
		} finally {
			WechatMpContext.switchOver();
		}
	}

	/**
	 * 调用企业微信
	 * @param function
	 * @return
	 */
	private <T> T callWork(Supplier<T> function) {
		//TODO 暂时不能用 需要等待支持企业微信
		throw new RuntimeException("暂未支持企业号功能， 请参考https://gitee.com/binary/weixin-java-tools/wikis/Home 相关说明自行实现");
	}

}



